﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Repetition.Views.Controls
{
    public class TypedListView<T> : ListView where T : class
    {
        Func<T, string> titleExtractor;

        public TypedListView(Func<T, string> titleExtractor)
        {
            this.titleExtractor = titleExtractor;
        }

        public void Add(T item)
        {
            string itemText = titleExtractor(item);
            Items.Add(new ListViewItem(itemText) { Tag = item });
        }

        public void Add(ICollection<T> items, bool clear)
        {
            this.BeginUpdate();

            if (clear)
                this.Items.Clear();

            foreach (var item in items)
                Add(item);
            
            this.EndUpdate();
        }

        public void Remove(T item)
        {
            int itemCount = Items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                if (Items[i].Tag == item)
                {
                    Items.RemoveAt(i);
                    break;
                }
            }
        }

        public T SelectedItem
        {
            get
            {
                if (base.SelectedItems.Count > 0)
                    return (T)base.SelectedItems[0].Tag;

                return null;
            }

            set
            {
                if (value != null)
                {
                    SelectedItems.Clear();
                    SelectedItems.Add(value);
                }
            }
        }

        public new ICollection<T> SelectedItems
        {
            get
            {
                var items = new List<T>();
                int selectedCount = base.SelectedItems.Count;

                foreach (int index in base.SelectedIndices)
                    items.Add((T)base.Items[index].Tag);

                return items;
            }
        }

        public void ClearSelection()
        {
            base.SelectedIndices.Clear();
        }

        public void SelectItem(T item)
        {
            var listViewItem = GetItem(item);

            if (listViewItem != null)
                listViewItem.Selected = true;
        }

        public void RefreshTitles()
        {
            int itemCount = base.Items.Count;
            for (int i = 0; i < itemCount; i++)
                base.Items[i].Text = titleExtractor((T)base.Items[i].Tag);
        }

        private ListViewItem GetItem(T tag)
        {
            int itemCount = base.Items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                if (tag == base.Items[i].Tag)
                    return base.Items[i];
            }

            return null;
        }
    }
}
